package com.isoftstone.controller;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.isoftstone.mapper.StudentMapper;
import com.isoftstone.pojo.Student;

import com.isoftstone.pojo.Users;
import com.isoftstone.pojo.dto.PasswordModifyDTO;
import com.isoftstone.pojo.dto.UpdateStudentDormDto;
import com.isoftstone.service.StudentService;
import com.isoftstone.util.BusinessException;
import com.isoftstone.util.FileUploadUtil;
import com.isoftstone.util.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@RestController
@RequestMapping("/api/student")
public class StudentController {
    @Autowired
    @Resource
    private StudentService studentService;
    @Autowired
    private StudentMapper studentMapper;
    @Resource
    private FileUploadUtil fileUploadUtil; // 注入文件工具类
    // 添加日志对象定义
    private static final Logger log = LoggerFactory.getLogger(StudentController.class);

    /**
     * 添加学生
     * @param student 学生信息
     * @return 操作结果
     */
    @PostMapping("/add")
    public Result<?> insertStudent( @RequestBody Student student) {
        return studentService.insertStudent(student);
    }
//    分页查询学生信息
    @GetMapping("/query")
    public Result<?> queryAllUser(@RequestParam (defaultValue ="1" ) Integer currentPage, @RequestParam (defaultValue ="4" ) Integer pageSize)
    {
        Page page = studentService.queryAllStudent(currentPage, pageSize);
        PageInfo<Object> pageInfo=new PageInfo<>(page);
        return Result.success(pageInfo);
    }
//    修改学生信息
    @PutMapping("/update")
    public Result<?> updateStudent(@RequestBody Student student) {
        return studentService.updateStudent(student);
    }
//    删除学生信息
    @DeleteMapping("/delete/{id}")
    public Result<?> deleteUser(@PathVariable Integer id) {

        return studentService.deleteStudent(id);
    }
    //批量删除
    @DeleteMapping("/batch")
    public Result<?> batchDeleteStudents(@RequestBody List<Long> ids) {
        try {
            if (ids == null || ids.isEmpty()) {
                return Result.error("请选择要删除的用户");
            }

            int deletedCount = studentService.batchDeleteStudents(ids);
            return Result.success("成功删除 " + deletedCount + " 个用户");
        } catch (Exception e) {
            return Result.error("批量删除失败: " + e.getMessage());
        }
    }
    /**
     * 根据用户名搜索用户
     * @param name 用户名
     * @param currentPage 当前页
     * @param pageSize 每页大小
     * @return 分页结果
     */
    @GetMapping("/search")
    public Result<?> searchUsers(
            @RequestParam(value = "name", required = false) String name,
            @RequestParam(value = "currentPage", defaultValue = "1") Integer currentPage,
            @RequestParam(value = "pageSize", defaultValue = "4") Integer pageSize) {

        try {
            Page  studentPage = studentService.searchStudentsByName(name, currentPage, pageSize);

            PageInfo<Object> pageInfo = new PageInfo<>(studentPage);
            return Result.success(pageInfo);
        } catch (Exception e) {
            return Result.error("搜索失败: " + e.getMessage());
        }
    }
    //    用户导入
    @PostMapping("/import")
    public Result<?> importExcel(MultipartFile file) throws IOException {
        // 添加日志对象定义（如果尚未定义）
        // private static final Logger log = LoggerFactory.getLogger(YourClassName.class);

        // 1.通过file对象获取输入流对象
        InputStream is = file.getInputStream();
        // 读取流
        ExcelReader excelReader = ExcelUtil.getReader(is);
        List<Student> students = excelReader.readAll(Student.class);

        int successCount = 0;
        int failCount = 0;
        StringBuilder errorMsg = new StringBuilder();

        for (Student student : students) {
            try {
                Result<?> result = studentService.insertStudent(student);
                // 根据code判断操作是否成功，而不是message
                if (result != null && result.getCode() == 200) {
                    successCount++;
                    log.info("学生 " + student.getName() + " 插入成功");
                } else {
                    failCount++;
                    String message = result != null ? result.getMessage() : "未知错误";
                    errorMsg.append("学生 ").append(student.getName())
                            .append(" 插入失败: ").append(message).append("; ");
                }
            } catch (Exception e) {
                failCount++;
                errorMsg.append("学生 ").append(student.getName())
                        .append(" 插入异常: ").append(e.getMessage()).append("; ");
                log.error("导入学生异常: " + e.getMessage(), e);
            }
        }

        // 构建返回消息
        String message = "导入完成，成功: " + successCount + "条，失败: " + failCount + "条";
        if (errorMsg.length() > 0) {
            message += "。错误信息: " + errorMsg.toString();
        }

        // 根据是否有失败记录返回不同的结果
        if (failCount > 0) {
            // 有失败记录，返回成功但带有警告信息
            return Result.success(message);
        } else {
            // 全部成功
            return Result.success(message);
        }
    }
    //用户导出
    @GetMapping("/export")
    public void exportExcel(HttpServletResponse response) throws IOException {
        studentService.exportExcel(response);
    }
    /**
     * 新增：按姓名+报到状态组合查询（支持分页）
     * @param name 学生姓名（非必选，模糊查询）
     * @param status 报到状态（非必选，精确查询，如"已报到"/"未报到"）
     * @param currentPage 当前页码（必选，默认1）
     * @param pageSize 每页条数（必选，默认10）
     * @return 分页后的报到信息（含分页元数据+当前页数据）
     */
    @GetMapping("/report-info/query-page")
    public Result<?> queryReportInfoByPage(
            // 查询条件：姓名（非必选，前端不传则不参与过滤）
            @RequestParam(value = "name", required = false) String name,
            // 查询条件：报到状态（非必选，前端不传则不参与过滤）
            @RequestParam(value = "status", required = false) String status,
            // 分页参数：当前页（默认1，避免前端不传导致空指针）
            @RequestParam(value = "currentPage", defaultValue = "1") Integer currentPage,
            // 分页参数：每页条数（默认10，可根据需求调整）
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {

        try {
            // 调用Service层，传入查询条件+分页参数
            PageInfo<Student> pageInfo = studentService.queryReportInfoByPage(name, status, currentPage, pageSize);

            if (pageInfo.getList() != null && !pageInfo.getList().isEmpty()) {
                log.info("按条件查询到 {} 条学生报到信息，当前第 {} 页", pageInfo.getTotal(), currentPage);
                return Result.success(pageInfo); // 成功返回分页对象
            } else {
                return Result.success("未查询到符合条件的学生报到信息", pageInfo); // 无数据仍返回分页元数据
            }
        } catch (Exception e) {
            log.error("按条件分页查询报到信息失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }



    /**
     * 1. 统计接口：查询系别总人数和各专业人数
     * 请求方式：GET
     * 示例URL：/api/student/statistics/dept-major
     */
    @GetMapping("/statistics/dept-major")
    public Result<?> statisticsDeptAndMajor() {
        return studentService.statisticsDeptAndMajor();
    }

    /**
     * 2. 多条件搜索接口：按姓名+系别+专业搜索学生（支持分页）
     * 请求方式：GET
     * 示例URL：/api/student/search/multi?department=计算机学院&major=软件工程&currentPage=1&pageSize=10
     */
    @GetMapping("/search/multi")
    public Result<?> searchStudentsByMultiCond(
            // 姓名（可选，模糊查询）
            @RequestParam(value = "name", required = false) String name,
            // 系别（可选，模糊查询）
            @RequestParam(value = "department", required = false) String department,
            // 专业（可选，模糊查询）
            @RequestParam(value = "major", required = false) String major,
            // 分页参数（默认第1页，每页10条）
            @RequestParam(value = "currentPage", defaultValue = "1") Integer currentPage,
            @RequestParam(value = "pageSize", defaultValue = "1000") Integer pageSize
    ) {
        return studentService.searchStudentsByMultiCond(name, department, major, currentPage, pageSize);
    }
    /**
     * 新增：修改学生的系别和专业
     * 请求方式：PUT
     * 示例URL：/api/student/update-dept-major?id=1&department=计算机学院&major=大数据专业
     * @param id 学生ID（路径参数/请求参数均可，这里用请求参数更直观）
     * @param department 新系别
     * @param major 新专业
     * @return 操作结果
     */
    @PutMapping("/update-dept-major")
    public Result<?> updateStudentDeptAndMajor(
            @RequestParam("id") Integer id,  // ID仍为必传
            @RequestParam(value = "department", required = false) String department,  // 系别非必传
            @RequestParam(value = "major", required = false) String major  // 专业非必传
    ) {
        return studentService.updateDeptAndMajor(id, department, major);
    }
    @GetMapping("/by-number")
    public Result<?> findByStudentNumber(@RequestParam String studentNumber) {
        return studentService.findByStudentNumber(studentNumber);
    }
    @PutMapping("/{studentNumber}/dorm")
    public Result<?> updateStudentDorm(@PathVariable String studentNumber, @RequestBody UpdateStudentDormDto dto) {
        return studentService.updateStudentDormitory(studentNumber, dto);
    }



    /**
     * 学生登录接口
     * @param phone 手机号
     * @param password 密码
     * @return 登录结果
     */
    @PostMapping("/login")
    public Result login(
            @RequestParam String phone,
            @RequestParam String password) {

        try {
            Student student = studentService.login(phone, password);

            if (student != null) {
                // 登录成功，可以在这里生成token返回
                return Result.success("登录成功", student);
            } else {
                return Result.error("手机号或密码错误");
            }
        } catch (Exception e) {
            return Result.error("登录失败：" + e.getMessage());
        }
    }
    /**
     * 学生注册接口
     * @param phone 手机号
     * @param password 要设置的密码
     * @return 注册结果
     */
    @PostMapping("/register")
    public Result register(
            @RequestParam String phone,
            @RequestParam String password) {

        try {
            studentService.register(phone, password);
            return Result.success("注册成功", null);
        } catch (BusinessException e) {
            return Result.error(e.getMessage());
        } catch (Exception e) {
            return Result.error("注册失败：" + e.getMessage());
        }
    }
    /**
     * 忘记密码接口
     * @param phone 手机号
     * @param newPassword 新密码
     * @return 重置结果
     */
    @PostMapping("/forgot-password")
    public Result forgotPassword(
            @RequestParam String phone,
            @RequestParam String newPassword) {

        try {
            studentService.resetPassword(phone, newPassword);
            return Result.success("密码重置成功", null);
        } catch (BusinessException e) {
            return Result.error(e.getMessage());
        } catch (Exception e) {
            return Result.error("密码重置失败：" + e.getMessage());
        }
    }




    // 从配置文件读取服务器地址（如 http://192.168.12.236:8080）
    @Value("${server.address:http://192.168.12.236:8080}")
    private String serverAddress;

    // 图片上传接口（前端uni.uploadFile对应此路径）
    @PostMapping("/upload")
    public Result uploadAvatar(
            @RequestParam("photo") MultipartFile photo, // 对应前端name: 'file'
            @RequestParam("studentNo") String studentNo) { // 对应前端传递的学生学号
        try {
            // 1. 保存文件到服务器，获取相对路径
            String relativePath = fileUploadUtil.saveAvatar(photo, studentNo);
            // 2. 拼接完整访问URL（如 http://192.168.12.236:8080/static/avatar/xxx.png）
            String avatarUrl = serverAddress + relativePath;
            // 3. 调用Service，将avatarUrl更新到student表的avatar_url字段
            studentService.updateAvatarUrl(studentNo, avatarUrl);
            // 4. 返回成功结果（前端用result.data获取URL）
            return Result.success(avatarUrl);
        } catch (Exception e) {
            return Result.error("上传失败：" + e.getMessage());
        }
    }
    /**
     * 学生修改密码接口
     */
    @PostMapping("/modify-password")
    public Result modifyPassword(@RequestBody PasswordModifyDTO dto,
                                 @RequestHeader("Authorization") String token) {
        // 从token中解析出学号(实际项目中需要完善JWT验证逻辑)
        String studentNumber = parseStudentNumberFromToken(token);
        if (studentNumber == null) {
            return Result.error("令牌无效或已过期");
        }
        return studentService.modifyPassword(studentNumber, dto);
    }

    /**
     * 解析token获取学号(简化实现)
     */
    private String parseStudentNumberFromToken(String token) {
        // 实际项目中应该使用JWT工具类解析
        // 这里简化处理，假设token格式为"Bearer 学号"
        if (token != null && token.startsWith("Bearer ")) {
            return token.substring(7);
        }
        return null;
    }
    /**
     * 明文直接覆盖密码（不加密、不验旧密码）
     * 仅用于演示，上线务必删除或加权限校验
     */
    @PutMapping("/reset-simple")
    public Result resetSimple(@RequestParam String studentNumber,
                              @RequestParam String newPassword) {
        if (newPassword.length() < 6) {
            return Result.error("密码至少6位");
        }
        studentMapper.updatePassword(studentNumber, newPassword);
        return Result.success("密码已更新");
    }

    /**
     * 根据学号查询学生及关联的宿舍信息
     * @param studentNumber 学号
     * @return 包含宿舍信息的学生对象
     */
    @GetMapping("/with-dormitory")
    public Result<Student> getStudentWithDormitory(@RequestParam String studentNumber) {
        return studentService.getStudentWithDormitory(studentNumber);
    }

}
